/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pos.Driving.Dashboard.Image;

import pos.Driving.Dashboard.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.media.j3d.*;
import javax.vecmath.*;
import pos.utils.*;

/**
 *
 * @author Administrator
 */
public class SpeedMeter extends TransformGroup implements Invokeable{
    private SpeedDesc currentSpeed=new SpeedDesc(0,0,0);
    private double speedRot=0, speedLimitRot=0;
    private float fxStep,fxPredictStep=3,overSpeedCounter=0;
    //private Attachable nextDevice;
    private OrderedGroup ogDashboard;
    private Plane2D planeDashboard, planeSpeedInfo, planePredictInfo;
    private TransformGroup tgSpeedPointer, tgSpeedLimitPointer,tgText,tgPredict;
    private Transform3D t2d=new Transform3D(), t3d=new Transform3D();
    private boolean is3D= false;
    
    public SpeedMeter(Transform3D transform,Transform3D t3d) {
        super(transform);
        this.t2d.set(transform);
        this.t3d.set(t3d);
        //this.setTransform(transform);
        this.setCapability(ALLOW_TRANSFORM_WRITE);
        initObjects();
        this.addChild(ogDashboard);
        setPointers();
    }

    public void setCurrentSpeed(SpeedDesc Speed) {
        if((Math.round(Speed.Speed)!=Math.round(currentSpeed.Speed)) ||
           (Math.round(Speed.SpeedTarget)!=Math.round(currentSpeed.SpeedTarget))||
           (Math.round(Speed.SpeedLimit)!=Math.round(currentSpeed.SpeedLimit))){
                this.currentSpeed = Speed;
                planeSpeedInfo.setTexture(makeSpeedInfoTexture());
        }else
            this.currentSpeed = Speed;
    }
    
    public void setNextSignture(String text){
        String predictText=text;
        fxPredictStep=100.0f;
        planePredictInfo.setTexture(makePredictInfoTexture(predictText));
        //this.nextDevice=nextDevice;
    }
    @Override
    public void invoke(double Step) {
        fxStep=(fxStep+(float)Step) % 100f;
        planeDashboard.setColor(new Color3f(1f,1f,1f));
        speedRot=-(currentSpeed.Speed/100d)*(4d/3d*Math.PI);
        double destSLRot=-(currentSpeed.SpeedLimit/100d)*(4d/3d*Math.PI);
        if (Math.abs(speedLimitRot-destSLRot)<Step*Math.PI)
            speedLimitRot=destSLRot;
        else if (speedLimitRot>destSLRot){
            speedLimitRot-=Step*Math.PI;
            planeDashboard.setColor(new Color3f(0.2f,0.2f,1f));
        }else{
            speedLimitRot+=Step*Math.PI;
            planeDashboard.setColor(new Color3f(0.2f,0.2f,1f));
        }
        if(currentSpeed.isOverSpeed()){
            planeDashboard.setColor(new Color3f(1f,
                    (float)Math.sin(fxStep*Math.PI*1.5),
                    (float)Math.sin(fxStep*Math.PI*1.5)));
        }
        
        setPointers();
        /*if (fxPredictStep>0) {
            fxPredictStep-=Step;
            planePredictInfo.setAlpha(0);
            if(fxPredictStep<1)
                planePredictInfo.setAlpha(1-fxPredictStep);
        }*/
    }
    public void setMode(boolean is3D){
        if (is3D == this.is3D)
            return;
        this.is3D=is3D;

        Transform3D tempT3D= new Transform3D();
        if (is3D){
            this.setTransform(t3d);
            tempT3D.set(new Vector3f(1.3f,1.0f,5f));
            this.tgText.setTransform(tempT3D);
            tempT3D.set(new Vector3f(1.8f,1.10f,5f));
            this.tgPredict.setTransform(tempT3D);
            planeDashboard.setAlpha(0.0f);
        }else{
            this.setTransform(t2d);
            tempT3D.set(new Vector3f(0.05f,-0.55f,0f));
            this.tgText.setTransform(tempT3D);
            tempT3D.set(new Vector3f(0.05f,0.55f,0f));
            this.tgPredict.setTransform(tempT3D);
            planeDashboard.setAlpha(0.1f);
        }
    }
    private void setPointers(){
        Transform3D t3dR=new Transform3D(),t3dT=new Transform3D();
        t3dR.rotZ(speedRot+Math.PI/3*2);
        t3dT.set(new Vector3f(0f,0.27f,0f));
        t3dR.mul(t3dT);
        tgSpeedPointer.setTransform(t3dR);
        
        t3dR.rotZ(speedLimitRot+Math.PI/3*2);
        t3dT.set(new Vector3f(0f,0.45f,0f));
        t3dR.mul(t3dT);
        tgSpeedLimitPointer.setTransform(t3dR);
        
    }
    private void initObjects(){
        ogDashboard=new OrderedGroup();
        planeDashboard=(Plane2D)ObjectFactory.createTexturedSurface(
                1f, 1f, 0f, new Color3f(1f,1f,1f), 0.1f, 
                PathRes.getPath("Image.DriveRoom.SpeedDash"));
        ogDashboard.addChild(planeDashboard);
        
        tgSpeedPointer=new TransformGroup();
        tgSpeedPointer.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        tgSpeedPointer.addChild(ObjectFactory.createTexturedSurface(
                0.05f, 0.3f, 0.01f, new Color3f(1f,1f,1f), 0f, 
                makeSpeedPointerTexture()));
        ogDashboard.addChild(tgSpeedPointer);
        
        tgSpeedLimitPointer=new TransformGroup();
        tgSpeedLimitPointer.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        tgSpeedLimitPointer.addChild(ObjectFactory.createTexturedSurface(
                0.05f, 0.08f, 0.02f, new Color3f(1f,1f,1f), 0f, 
                makeSpeedLimitPointerTexture()));
        ogDashboard.addChild(tgSpeedLimitPointer);
        
        tgText=new TransformGroup();
        Transform3D t3dT=new Transform3D();
        tgText.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        t3dT.set(new Vector3f(0.05f,-0.55f,0f));
        tgText.setTransform(t3dT);
        tgText.addChild(ObjectFactory.createTexturedSurface(
                1f, 0.125f, 0f, new Color3f(1f,1f,1f), 0f, 
                makeSpeedInfoBackTexture()));
        planeSpeedInfo=(Plane2D)ObjectFactory.createTexturedSurface(
                1f, 0.125f, 0f, new Color3f(1f,1f,1f), 0f, 
                makeSpeedInfoTexture());
        tgText.addChild(planeSpeedInfo);
        ogDashboard.addChild(tgText);
        
        tgPredict=new TransformGroup();
        tgPredict.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        t3dT.set(new Vector3f(0.05f,0.55f,0f));
        tgPredict.setTransform(t3dT);
        planePredictInfo=(Plane2D)ObjectFactory.createTexturedSurface(
                1.4f, 0.09f, 0f, new Color3f(1f,1f,1f), 0f, 
                makePredictInfoTexture(""));
        tgPredict.addChild(planePredictInfo);
        ogDashboard.addChild(tgPredict);
    }


    private Texture2D makePredictInfoTexture(String text) {
        BufferedImage tabBuffer = new BufferedImage(256, 16, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = (Graphics2D) tabBuffer.getGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2d.setFont(new Font("SimHei",Font.PLAIN,16));
        g2d.setPaint(Color.red);
        g2d.drawString(text, 0, 14);
        ImageComponent2D ic2D = new ImageComponent2D(ImageComponent.FORMAT_RGBA, tabBuffer, true, false);
        Texture2D textureOut = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, 256, 16);
        textureOut.setImage(0, ic2D);
        return textureOut;
    }
    
    private Texture2D makeSpeedInfoTexture() {
        BufferedImage tabBuffer = new BufferedImage(256, 32, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = (Graphics2D) tabBuffer.getGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2d.setFont(new Font("SimHei",Font.PLAIN,24));
        g2d.setPaint(Color.blue);
        g2d.drawString(Math.round(currentSpeed.Speed)+"", 54, 24);
        g2d.setPaint(Color.yellow);
        g2d.drawString(Math.round(currentSpeed.SpeedTarget)+"", 136, 24);
        g2d.setPaint(Color.red);
        g2d.drawString(Math.round(currentSpeed.SpeedLimit)+"", 220,24);
        ImageComponent2D ic2D = new ImageComponent2D(ImageComponent.FORMAT_RGBA, tabBuffer, true, false);
        Texture2D textureOut = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, 256, 32);
        textureOut.setImage(0, ic2D);
        return textureOut;
    }
    private Texture2D makeSpeedInfoBackTexture() {
        BufferedImage tabBuffer = new BufferedImage(256, 32, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = (Graphics2D) tabBuffer.getGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2d.setFont(new Font("SimHei",Font.PLAIN,24));
        g2d.setPaint(Color.blue);
        g2d.drawString("实际", 0, 24);
        g2d.setPaint(Color.yellow);
        g2d.drawString("目标", 86, 24);
        g2d.setPaint(Color.red);
        g2d.drawString("限制", 172,24);
        ImageComponent2D ic2D = new ImageComponent2D(ImageComponent.FORMAT_RGBA, tabBuffer, true, false);
        Texture2D textureOut = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, 256, 32);
        textureOut.setImage(0, ic2D);
        return textureOut;
    }
    
    private Texture2D makeSpeedPointerTexture() {
        Polygon SpeedDashPointer=new Polygon(new int[]{0,0,5,7,8,10,15,15},
            new int[]{64,40,32,0,0,32,40,64},8);
        BufferedImage tabBuffer = new BufferedImage(16, 64, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = (Graphics2D) tabBuffer.getGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2d.setPaint(Color.yellow);
        g2d.fill(SpeedDashPointer);
        ImageComponent2D ic2D = new ImageComponent2D(ImageComponent.FORMAT_RGBA, tabBuffer, true, false);
        Texture2D textureOut = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, 16, 64);
        textureOut.setImage(0, ic2D);
        return textureOut;
    }
    
    private Texture2D makeSpeedLimitPointerTexture() {
        Polygon SpeedLimitPointer=new Polygon(new int[]{0,32,32,16,0},
            new int[]{0,0,20,32,20},5);
        BufferedImage tabBuffer = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = (Graphics2D) tabBuffer.getGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2d.setPaint(Color.red);
        g2d.fill(SpeedLimitPointer);
        ImageComponent2D ic2D = new ImageComponent2D(ImageComponent.FORMAT_RGBA, tabBuffer, true, false);
        Texture2D textureOut = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, 32, 32);
        textureOut.setImage(0, ic2D);
        return textureOut;
    }
}
